home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / rpclib / rpc_prot.c < prev    next >
C/C++ Source or Header  |  1994-03-09  |  7KB  |  293 lines

  1. /*
  2.  * $Id: rpc_prot.c,v 1.2 1993/11/10 02:40:29 jraja Exp $
  3.  *
  4.  * $Log: rpc_prot.c,v $
  5.  * Revision 1.2  1993/11/10  02:40:29  jraja
  6.  * Added XDRFUN's + some prototypes.
  7.  *
  8.  */
  9. /* @(#)rpc_prot.c    2.3 88/08/07 4.0 RPCSRC */
  10. /*
  11.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  12.  * unrestricted use provided that this legend is included on all tape
  13.  * media and as a part of the software program in whole or part.  Users
  14.  * may copy or modify Sun RPC without charge, but are not authorized
  15.  * to license or distribute it to anyone else except as part of a product or
  16.  * program developed by the user.
  17.  * 
  18.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  19.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  20.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  21.  * 
  22.  * Sun RPC is provided with no support and without any obligation on the
  23.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  24.  * modification or enhancement.
  25.  * 
  26.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  27.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  28.  * OR ANY PART THEREOF.
  29.  * 
  30.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  31.  * or profits or other special, indirect and consequential damages, even if
  32.  * Sun has been advised of the possibility of such damages.
  33.  * 
  34.  * Sun Microsystems, Inc.
  35.  * 2550 Garcia Avenue
  36.  * Mountain View, California  94043
  37.  */
  38. #if !defined(lint) && defined(SCCSIDS)
  39. static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
  40. #endif
  41.  
  42. /*
  43.  * rpc_prot.c
  44.  *
  45.  * Copyright (C) 1984, Sun Microsystems, Inc.
  46.  *
  47.  * This set of routines implements the rpc message definition,
  48.  * its serializer and some common rpc utility routines.
  49.  * The routines are meant for various implementations of rpc -
  50.  * they are NOT for the rpc client or rpc service implementations!
  51.  * Because authentication stuff is easy and is part of rpc, the opaque
  52.  * routines are also in this program.
  53.  */
  54.  
  55. #include <sys/param.h>
  56. #include <rpc/rpc.h>
  57.  
  58. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  59.  
  60. /* struct opaque_auth _null_auth; This is defined in the rpc_commondata.c*/
  61.  
  62. /*
  63.  * XDR an opaque authentication struct
  64.  * (see auth.h)
  65.  */
  66. bool_t XDRFUN
  67. xdr_opaque_auth(xdrs, ap)
  68.     register XDR *xdrs;
  69.     register struct opaque_auth *ap;
  70. {
  71.  
  72.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  73.         return (xdr_bytes(xdrs, &ap->oa_base,
  74.             &ap->oa_length, MAX_AUTH_BYTES));
  75.     return (FALSE);
  76. }
  77.  
  78. /*
  79.  * XDR a DES block
  80.  */
  81. bool_t XDRFUN
  82. xdr_des_block(xdrs, blkp)
  83.     register XDR *xdrs;
  84.     register des_block *blkp;
  85. {
  86.     return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
  87. }
  88.  
  89. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  90.  
  91. /*
  92.  * XDR the MSG_ACCEPTED part of a reply message union
  93.  */
  94. bool_t  XDRFUN
  95. xdr_accepted_reply(xdrs, ar)
  96.     register XDR *xdrs;   
  97.     register struct accepted_reply *ar;
  98. {
  99.  
  100.     /* personalized union, rather than calling xdr_union */
  101.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  102.         return (FALSE);
  103.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  104.         return (FALSE);
  105.     switch (ar->ar_stat) {
  106.  
  107.     case SUCCESS:
  108.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  109.  
  110.     case PROG_MISMATCH:
  111.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  112.             return (FALSE);
  113.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  114.     }
  115.     return (TRUE);  /* TRUE => open ended set of problems */
  116. }
  117.  
  118. /*
  119.  * XDR the MSG_DENIED part of a reply message union
  120.  */
  121. bool_t  XDRFUN
  122. xdr_rejected_reply(xdrs, rr)
  123.     register XDR *xdrs;
  124.     register struct rejected_reply *rr;
  125. {
  126.  
  127.     /* personalized union, rather than calling xdr_union */
  128.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  129.         return (FALSE);
  130.     switch (rr->rj_stat) {
  131.  
  132.     case RPC_MISMATCH:
  133.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  134.             return (FALSE);
  135.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  136.  
  137.     case AUTH_ERROR:
  138.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  139.     }
  140.     return (FALSE);
  141. }
  142.  
  143. static struct xdr_discrim reply_dscrm[3] = {
  144.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  145.     { (int)MSG_DENIED, xdr_rejected_reply },
  146.     { __dontcare__, NULL_xdrproc_t } };
  147.  
  148. /*
  149.  * XDR a reply message
  150.  */
  151. bool_t XDRFUN
  152. xdr_replymsg(xdrs, rmsg)
  153.     register XDR *xdrs;
  154.     register struct rpc_msg *rmsg;
  155. {
  156.     if (
  157.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  158.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  159.         (rmsg->rm_direction == REPLY) )
  160.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  161.            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  162.     return (FALSE);
  163. }
  164.  
  165.  
  166. /*
  167.  * Serializes the "static part" of a call message header.
  168.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  169.  * The rm_xid is not really static, but the user can easily munge on the fly.
  170.  */
  171. bool_t XDRFUN
  172. xdr_callhdr(xdrs, cmsg)
  173.     register XDR *xdrs;
  174.     register struct rpc_msg *cmsg;
  175. {
  176.  
  177.     cmsg->rm_direction = CALL;
  178.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  179.     if (
  180.         (xdrs->x_op == XDR_ENCODE) &&
  181.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  182.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  183.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  184.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  185.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  186.     return (FALSE);
  187. }
  188.  
  189. /* ************************** Client utility routine ************* */
  190.  
  191. static void
  192. accepted(enum accept_stat acpt_stat, struct rpc_err * error)
  193. {
  194.  
  195.     switch (acpt_stat) {
  196.  
  197.     case PROG_UNAVAIL:
  198.         error->re_status = RPC_PROGUNAVAIL;
  199.         return;
  200.  
  201.     case PROG_MISMATCH:
  202.         error->re_status = RPC_PROGVERSMISMATCH;
  203.         return;
  204.  
  205.     case PROC_UNAVAIL:
  206.         error->re_status = RPC_PROCUNAVAIL;
  207.         return;
  208.  
  209.     case GARBAGE_ARGS:
  210.         error->re_status = RPC_CANTDECODEARGS;
  211.         return;
  212.  
  213.     case SYSTEM_ERR:
  214.         error->re_status = RPC_SYSTEMERROR;
  215.         return;
  216.  
  217.     case SUCCESS:
  218.         error->re_status = RPC_SUCCESS;
  219.         return;
  220.     }
  221.     /* something's wrong, but we don't know what ... */
  222.     error->re_status = RPC_FAILED;
  223.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  224.     error->re_lb.s2 = (long)acpt_stat;
  225. }
  226.  
  227. static void 
  228. rejected(enum reject_stat rjct_stat, struct rpc_err * error)
  229. {
  230.  
  231.     switch (rjct_stat) {
  232.  
  233.     case RPC_VERSMISMATCH:
  234.         error->re_status = RPC_VERSMISMATCH;
  235.         return;
  236.  
  237.     case AUTH_ERROR:
  238.         error->re_status = RPC_AUTHERROR;
  239.         return;
  240.     }
  241.     /* something's wrong, but we don't know what ... */
  242.     error->re_status = RPC_FAILED;
  243.     error->re_lb.s1 = (long)MSG_DENIED;
  244.     error->re_lb.s2 = (long)rjct_stat;
  245. }
  246.  
  247. /*
  248.  * given a reply message, fills in the error
  249.  */
  250. void
  251. _seterr_reply(msg, error)
  252.     register struct rpc_msg *msg;
  253.     register struct rpc_err *error;
  254. {
  255.  
  256.     /* optimized for normal, SUCCESSful case */
  257.     switch (msg->rm_reply.rp_stat) {
  258.  
  259.     case MSG_ACCEPTED:
  260.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  261.             error->re_status = RPC_SUCCESS;
  262.             return;
  263.         };
  264.         accepted(msg->acpted_rply.ar_stat, error);
  265.         break;
  266.  
  267.     case MSG_DENIED:
  268.         rejected(msg->rjcted_rply.rj_stat, error);
  269.         break;
  270.  
  271.     default:
  272.         error->re_status = RPC_FAILED;
  273.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  274.         break;
  275.     }
  276.     switch (error->re_status) {
  277.  
  278.     case RPC_VERSMISMATCH:
  279.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  280.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  281.         break;
  282.  
  283.     case RPC_AUTHERROR:
  284.         error->re_why = msg->rjcted_rply.rj_why;
  285.         break;
  286.  
  287.     case RPC_PROGVERSMISMATCH:
  288.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  289.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  290.         break;
  291.     }
  292. }
  293.